/**
 * @module utils/StyleListUtil
 * @desc 式样表工具
 */

import {
  getCenter
} from '../mapUtils/GeometryUtil';
import {
  projectWebMercatorToLngLat
} from '../mapUtils/CoordinateUtil';
import POINT_DEVICE from '../constant/PointDevice';

let StyleMapping = {};
let StyleList = {};
let currentStyle = null;

/**
 * 转换式样公式
 * @param {*} source 式样表
 * @ignore
 */
function parseMatchExpression(source) {
  let rtn = {};
  let expressionName = source[0];
  if (expressionName === 'match') {
    let conditionType = source[1][0];
    let conditionField = source[1][1];
    rtn.type = conditionType;
    rtn.field = conditionField;
    rtn.default = source[source.length - 1];
    let values = source.slice(2);
    rtn.data = {};
    for (let i = 0; i < values.length - 1; i += 2) {
      const element = values[i];
      rtn.data[element] = values[i + 1] || rtn.default;
    }
  }
  return rtn;
}
/**
 * 格式化样式，缓存样式表
 * @param {*} style 式样表
 * @param {*} key 式样名
 * @ignore
 */
function parseStyleMapping(style, key) {
  let rtn = {};
  if (!style[key]) {
    return '{}';
  }
  let source = '';
  try {
    source = JSON.parse(style[key]);
  } catch (error) {
    source = style[key];
    return {
      type: '',
      value: style[key]
    };
  }
  // console.log(source);
  let expressionName = source[0];
  if (expressionName === 'interpolate') {
    let conditionType = source[1],
      conditionField = source[2];
    rtn.type = conditionType;
    rtn.field = conditionField;

    let defaultValue = 1;
    let values = source.slice(3);

    rtn.default = defaultValue;
    rtn.kv = {};
    for (let i = 0; i < values.length; i += 2) {
      const element = values[i];
      rtn.kv[element] = values[i + 1];
    }
  } else if (expressionName === 'step') {
    let conditionType = source[1][0],
      conditionField = source[1][1];
    rtn.type = conditionType;
    rtn.field = conditionField;

    let defaultValue = source[2];
    let values = source.slice(3);

    rtn.default = defaultValue;
    rtn.kv = {};
    for (let i = 0; i < values.length; i += 2) {
      const element = values[i];
      rtn.kv[element] = values[i + 1];
    }
    Object.keys(rtn.kv).forEach((keyinner) => {
      //如果有嵌套match语法，临时使用，后面可以写成递归
      if (Array.isArray(rtn.kv[keyinner])) {
        rtn.kv[keyinner] = parseMatchExpression(rtn.kv[keyinner]);
      }
    });
  }
  // console.log(rtn);
  return rtn;
}
/**
 * 解析转换式样
 * @param {Number} sysDsno 显示放案
 * @param {Array} styleList 式样列表
 * @ignore
 */
function parseStyle(sysDsno, styleList) {
  if (styleList.lineStyle) {
    styleList.lineStyle.forEach((style) => {
      StyleMapping[sysDsno][style.sbzlx] = {
        lineColor: parseStyleMapping(style, 'line_color'),
        lineWidth: parseStyleMapping(style, 'line_width'),
        lineOpacity: parseStyleMapping(style, 'line_opacity')
      };
    });
  }
  if (styleList.pointStyle) {
    styleList.pointStyle.forEach((style) => {
      StyleMapping[sysDsno][style.sbzlx] = {
        iconImage: parseStyleMapping(style, 'icon_image'),
        iconSize: parseStyleMapping(style, 'icon_size'),
        textColor: parseStyleMapping(style, 'text_color')
        // iconRotate: parseStyleMapping(style, "icon_rotate"),
      };
    });
  }
}
/**
 * 初始化样式列表
 * @param {Object} styleList 式样列表
 */
export function initialStyleList(styleList) {
  StyleList = styleList;
  let sysDsnos = Object.keys(styleList);
  currentStyle = sysDsnos[0];
  sysDsnos.forEach((sysDsno) => {
    StyleMapping[sysDsno] = {};
    parseStyle(sysDsno, styleList[sysDsno]);
  });
}

/**
 * 设置显示方案
 * @param {Number} sysDsno 显示方案
 */
export function setCurrentStyle(sysDsno) {
  currentStyle = sysDsno;
}

/**
 * 获取所有式样列表
 */
export function getAllStyle() {
  return StyleList[currentStyle];
}

/**
 * 根据显示方案获取所有式样列表
 * @param {Number} sysDsno 显示方案
 */
export function getAllStyleByDsno(sysDsno) {
  return StyleList[sysDsno];
}

/**
 * 获取真实设备子类型
 * @param {Object} item 设备
 * @ignore
 */
function getTruthSbzlx(item) {
  return item.versionid > 0 ? Number('8' + item.sbzlx) : item.sbzlx;
}


/**
 * 获取线性值
 * @param {*} minkey 最小值名称
 * @param {*} maxkey 最大值名称
 * @param {*} minval 最小值
 * @param {*} maxval 最大值
 * @param {*} key 名称
 * @ignore
 */
function getLinearValue(minkey, maxkey, minval, maxval, key) {
  if (maxval === minval) {
    return maxval;
  }
  return (key - minkey) / (maxkey - minkey) * (maxval - minval) + minval;
}


/**
 * 获取数值在数组中的位置
 * @param {Array} keys 需要查找的数组
 * @param {Number} key 需要查找的值
 * @ignore
 */
function findNearleastKeys(sourcekeys, value) {
  let keys = sourcekeys.slice(0);
  let index = keys.indexOf(value);
  if (keys.indexOf(value) === -1) {
    // 不存在需要查找的值，
    // 添加数值
    keys.push(value);
    // 排序
    keys.sort();
    // 查找
    index = keys.indexOf(value);
    if (index === 0) {
      return [0, 0];
    } else if (index === keys.length - 1) {
      return [index - 1, index - 1];
    }
    return [index - 1, index];

  }
  return [index, index];

}

/**
 * 获取显示方案的具体算法
 * @param {*} source 式样表
 * @param {*} item 设备对象
 * @param {*} mapinfo 地图信息
 * @ignore
 */
function getPropertyStyle(source, item, mapinfo) {
  if (!source) {
    return null;
  }
  let conditionType = source.type,
    conditionField = source.field;

  if (conditionType === '') {
    return source.value;
  }
  let defaultValue = source.default,
    kv = source.kv;
  let sortedKeys = Object.keys(kv)
    .map((k) => k * 1)
    .sort();
  let needFound = null;
  if (conditionField === 'zoom') {
    needFound = mapinfo[conditionField];
  } else {
    needFound = item[conditionField];
  }
  if (conditionType === 'get') {
    if (Object.prototype.hasOwnProperty.call(kv, needFound)) {
      // 如果有嵌套match语法，临时使用，后面可以写成递归
      if (typeof kv[needFound] === 'object') {
        let data = kv[needFound].data;
        let key = item[kv[needFound].field];
        // console.log(data,key);
        if (data[key]) {
          return data[key];
        }
        return kv[needFound].default;

      }
      return kv[needFound];

    }
    // console.log('return ',defaultValue);
    return defaultValue;

  } else if (conditionType === 'linear') {
    let indeies = findNearleastKeys(sortedKeys, needFound);
    let minIndex = indeies[0],
      maxIndex = indeies[1];
    let minKeyValue = sortedKeys[minIndex],
      maxKeyValue = sortedKeys[maxIndex];
    if (minIndex === 0 && maxIndex === 0 && needFound !== sortedKeys[0]) {
      return defaultValue;
    }
    return getLinearValue(
      sortedKeys[minIndex],
      sortedKeys[maxIndex],
      kv[minKeyValue],
      kv[maxKeyValue],
      needFound
    );

  }
  console.info('未处理的条件类型', conditionType);
  return 1;

}
/**
 * 获取显示方案
 * @param {*} item 设备对象
 * @param {*} mapinfo 地图信息
 * @param {Number} sysDsno 显示方案
 */
export function getStyle(item, mapinfo, sysDsno) {
  var _sysDsno = sysDsno || currentStyle;
  let sbzlx = getTruthSbzlx(item);
  let styleSource = StyleMapping[_sysDsno][sbzlx];
  let style = {};
  if (styleSource) {
    style = {
      iconSize: getPropertyStyle(styleSource.iconSize, item, mapinfo),
      iconImage: getPropertyStyle(styleSource.iconImage, item, mapinfo),
      textColor: getPropertyStyle(styleSource.textColor, item, mapinfo),
      lineColor: getPropertyStyle(styleSource.lineColor, item, mapinfo),
      lineWidth: getPropertyStyle(styleSource.lineWidth, item, mapinfo),
      lineOpacity: getPropertyStyle(styleSource.lineOpacity, item, mapinfo),
      iconRotate: getPropertyStyle(styleSource.iconRotate, item, mapinfo)
    };
  } else {
    // console.log("sbzlx", sbzlx, "无法解析");
    style = {
      iconSize: '',
      iconImage: '',
      textColor: '',
      lineColor: '',
      lineWidth: '',
      lineOpacity: '',
      iconRotate: ''
    };
  }
  return style;
}


/**
 * 生成点的feature
 * @param {feature} point 点数据
 * @param {Object} style 式样
 * @ignore
 */
function getPointFeature(point) {
  let coordinates = point.geometry.type === 'Point' ? point.geometry.coordinates : getCenter(point.geometry.coordinates);
  let feature = turf.point(projectWebMercatorToLngLat(coordinates));
  feature.properties = Object.assign({}, point, {});
  // feature.properties.size = style.iconSize;
  // feature.properties.color = style.textColor;
  // feature.properties.opacity = 1;
  // feature.properties.GlobalMarkLabelField = style.GlobalMarkLabelField || "";
  feature.properties.sourceType = 'Point';
  return feature;
}

/**
 * 生成图标的feature
 * @param {feature} marker 点数据
 * @param {Object} style 式样
 * @ignore
 */
function getMarkerFeature(marker) {
  let coordinates = marker.geometry.type === 'Point' ?
    marker.geometry.coordinates : getCenter(marker.geometry.coordinates);
  let feature = turf.point(projectWebMercatorToLngLat(coordinates));
  feature.properties = Object.assign({}, marker, {});
  // feature.properties.icon = style.iconImage;
  // feature.properties.iconSize = style.iconSize;
  // feature.properties.iconRotate = style.iconRotate;
  // feature.properties.textColor = style.textColor;
  // feature.properties.opacity = 1;
  // feature.properties.GlobalMarkLabelField = style.GlobalMarkLabelField || "";
  feature.properties.sourceType = 'Marker';
  return feature;
}
// 只获取最后一个点
function getLastMarkerFeature(marker) {
  let coordinates = marker.geometry.type === 'Point' ?
    marker.geometry.coordinates : marker.geometry.coordinates[marker.geometry.coordinates.length - 1];
  let feature = turf.point(projectWebMercatorToLngLat(coordinates));
  feature.properties = Object.assign({}, marker, {});
  // feature.properties.icon = style.iconImage;
  // feature.properties.iconSize = style.iconSize;
  // feature.properties.iconRotate = style.iconRotate;
  // feature.properties.textColor = style.textColor;
  // feature.properties.opacity = 1;
  // feature.properties.GlobalMarkLabelField = style.GlobalMarkLabelField || "";
  feature.properties.sourceType = 'Marker';
  return feature;
}

/**
 * 生成线的feature
 * @param {feature} marker 点数据
 * @param {Object} style 式样
 * @ignore
 */
function getLineFeature(line) {
  let sourceType = line.geometry.type;
  let methodName = sourceType.charAt(0).toLowerCase() + sourceType.slice(1);
  let feature = turf[methodName](projectWebMercatorToLngLat(line.geometry.coordinates));
  // console.log("对于线的feature", feature);
  feature.properties = Object.assign({}, line, {});
  // feature.properties.color = style.lineColor;
  // feature.properties.width = style.lineWidth * 1;
  // feature.properties.opacity = style.lineOpacity * 1;
  // feature.properties.GlobalMarkLabelField = style.GlobalMarkLabelField || "";
  feature.properties.sourceType = sourceType;
  return feature;
}

/**
 * 生成多边形的feature
 * @param {feature} polygon 多边形数据
 * @param {Object} style 式样
 * @ignore
 */
function getPolygonFeature(polygon) {
  let sourceType = polygon.geometry.type;
  let methodName = sourceType.charAt(0).toLowerCase() + sourceType.slice(1);
  let feature = turf[methodName](projectWebMercatorToLngLat(polygon.geometry.coordinates));
  feature.properties = Object.assign({}, polygon, {});
  // feature.properties.color = style && style.color ? style.color : "";
  // feature.properties.opacity = style && style.opacity ? style.opacity : "";
  // feature.properties.GlobalMarkLabelField = style.GlobalMarkLabelField || "";
  feature.properties.sourceType = sourceType;
  return feature;
}

/**
 * 将设备数据转化成feature
 * @param {*} item 设备数据
 * @param {*} flag 是否线性设备
 */
export function formatDeviceFeature(item, flag) {
  let feature = null;
  let geometry = item.geometry;
  let geometryType = geometry.type;
  switch (geometryType) {
    case 'Point':
      if (item.sblx * 1 === 620000 || item.sbzlx * 1 === 62000002) {
        feature = getPointFeature(item);
      } else {
        feature = getMarkerFeature(item);
      }
      break;
    case 'LineString':
    case 'MultiLineString':
      if (POINT_DEVICE.indexOf(item.sbzlx * 1) >= 0 && (!flag)) {
        feature = getMarkerFeature(item);
      } else if (flag === 1) {
        feature = getLastMarkerFeature(item);
      } else {
        feature = getLineFeature(item);
      }
      break;
    case 'Polygon':
      if (item.sblx * 1 === 300000 || POINT_DEVICE.indexOf(item.sbzlx * 1) >= 0) {
        feature = getMarkerFeature(item);
      } else {
        feature = getPolygonFeature(item);
      }
      break;
    default:
      console.error(item.sbzlx, item.oid, item.sbmc, '未渲染');
  }
  if (feature) {
    feature.properties.GlobalMarkLabelField = item.sbmc || '';
  }
  return feature;
}